#requires -version 2.0 
Function Get-NaLun {
	<#
	.Synopsis
  	 	Get the status of the given LUN, or all LUNs.
	.Description
   		Get the status (size, online/offline state, shared state, comment string,
   		serial number, LUN mapping) of the given LUN, or all LUNs.
	.Parameter Path
   		Path of LUN. If specified, only the information of that LUN is returned.
   		If not specified, then information of all LUNs are returned. 
	.Parameter Server
   		NaServer to query
	.Example
		# Get 
		Get-NaLun -Path /vol/vol_test/lun1
	.Outputs
    	NetApp.SDK.NaLun[]
    .Link
		Set-NaLun
		New-NaLun
		Remove-NaLun
		Move-NaLun
		Set-NaLunSize
   #> 
	[CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")]
	param ( 
		[Parameter(ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")]
		[string]
		$Path,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-list-info")
		#$request.AddNewChild("get-clone-backing-snapshot",$True)
		if ($Path) {
			$request.AddNewChild("path",$Path)
		}
		try {
			$result  = ([xml]$server.InvokeElem($request)).results
		}
		catch [NetApp.Manage.NaApiFailedException]{
			Write-Warning $_.Exception.GetBaseException().message
			$result = $null
			continue;
		}
		if ($? -and $result.luns){
			if (ConvertFrom-NaBool $result."are-vols-onlining") {
				Write-Warning "Volumes are still in the process of onlining.the output of this command cannot be considered authoritative."
			}
			$result."luns"."lun-info" |% {
				return New-Object NetApp.SDK.NaLun -ArgumentList @(
					$_."path",
					$_."size",
					$_."block-size",
					(ConvertFrom-NaBool $_."online"),
					$_."serial-number",
					(ConvertFrom-NaBool $_."read-only"),
					(ConvertFrom-NaBool $_."is-space-reservation-enabled"),
					(ConvertFrom-NaBool $_."mapped"),
					$_."multiprotocol-type",
					$_."share-state",
					$_."uuid",
					$_."device-id",
					$_."backing-snapshot",
					$_."clone-backing-snapshot"
				)
			}
		}
	}
}
Function New-NaLun {
	<#
	.Synopsis
  	 	Create a new lun
	.Description
   		Create a new lun, with initially zero contents. The lun is 
   		created at the path given. No file should already exist at the given 
   		path.
	.Parameter Path
   		Path of the LUN. 
   	.Parameter Size
   		New size for the LUN in bytes. 
   		
   		Create a new lun of given size, with initially zero contents. The lun is 
   		created at the path given. No file should already exist at the given 
   		path. The directory specified in the path must be a qtree root directory. 
   		The size of the created lun could be larger than the size specified, in 
   		order to get an integral number of cylinders while reporting the geometry
   		using SAN protocols.
   	.Parameter FromFile
   		A fully qualified filer path to the file to create the LUN from. This must
   		be in the same qtree as the LUN being created. 
   		
   		Create a lun from an existing file. A new lun is created, at the given path
   		(which must be at a qtree root). A hard link is created to the existing file.
   		The file contents are not copied or changed. The file can be resized to a 
   		larger size, rounding up to a cylinder boundary.
   	.Parameter FromSnapshot
   		LUN path in the snapshot to be created from. 
   		
   		Creates a LUN in the active file system. The lun has the same initial contents
   		as the referenced snapshot copy of an existing lun. (Note that no copy of the
   		data is made.) Future writes go into the new lun. Reads of unmodified data are
   		satisfied from the snapshot location. Reads of modified data are satisfied by
   		first attempting to find the required buffer in the new lun. If a buffer is 
   		not found (buffer corresponds to a hole), it is looked for in the snapshot 
   		copy instead.
   	.Parameter OSType
   		Type of LUN. While optional, the caller should specify a non-default ostype.
   		Currently, supported ostypes: 
   		
   		"solaris" 
   		the lun will be used to store a Solaris raw disk in a single-slice partition
   		
   		"windows" 
   		the lun will be used to store a raw disk device in a single-partition Windows disk
   		
   		"hpux"
   		the lun will be used to store HP-UX data
   		
   		"aix"
   		the lun will be used to store AIX data
   		
   		"linux" 
   		the lun will be used to store a Linux raw disk without any partition table
   		
   		"netware" 
   		the lun will be used to store NetWare data
   		
   		"vmware" 
   		the lun will be used to store VMWARE data
   		
   		"windows_gpt" 
   		the lun will be used to store Windows data using the GPT partitioning style
   		
   		"windows_2008" 
   		the lun will be used to store Windows data on Windows 2008 systems
   		
   		"openvms"
   		the lun will be used to store OpenVMS data
   	.Parameter NoSpaceReserve
   		By default, the lun is space-reserved. If it is desired to manage space usage
   		manually instead, the NoSpaceReserve switch will create a LUN without any
   		space being reserved. 
	.Parameter Server
   		NaServer to query
	.Example
		#Create a 20GB LUN Named lun0 in vmdata3
		PS > New-NaLun -Path /vol/vmdata3/lun0 -Size 20GB
	.Example
		# Create a new lun from a snapshot
		PS > New-NaSnapshot -Name clone_base -Volume vmdata3
		PS > New-NaLun -Path /vol/vmdata3/lun2 -FromSnapshot /vol/vmdata3/.snapshot/clone_base/lun0 -NoSpaceReserve
	.Outputs
    	NetApp.SDK.NaLun[]
    .Link
		Get-NaLun
		Set-NaLun
		Remove-NaLun
		Move-NaLun
   	.Notes 
	    NAME:     New-NaLun
	    AUTHOR:   Glenn Sizemore
	    #Requires -Version 2.0 
	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
    param (
		[Parameter(Mandatory=$TRUE,Position=0,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
		[STRING]
    	$Path,
		
	    [Parameter(Mandatory=$TRUE,ParameterSetName="size",ValueFromPipelineByPropertyName=$TRUE,HelpMessage="New size for the LUN in Bytes.")]
		[Int64]
    	$Size,
		
		[Parameter(Mandatory=$TRUE,ParameterSetName="file",HelpMessage="A fully qualified filer path to the file to create the LUN from.")]
		[string]
		$FromFile,
		
		[Parameter(Mandatory=$TRUE,ParameterSetName="snapshot",HelpMessage="LUN path in the snapshot to be created from.")]
		[string]
		$FromSnapshot,
		
		[Parameter(Position=2,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="The ostype for the LUN.")]
		[ValidateSet("image", "solaris", "windows", "hpux", "aix", "linux", "netware", "vmware", "windows_gpt", "windows_2008", "openvms")]
		[string]
		$OSType,
		
		[Parameter()]
		[switch]
		$NoSpaceReserve,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
    )
	process {    
		if ($Server.Version -gt 1.8) {
			if ($FromFile) {
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-file")
				$request.AddNewChild("file-name",$FromFile)
				if ($OSType) {
					$request.AddNewChild("ostype", $OSType)
				}
			} elseif ($FromSnapshot) {
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-snapshot")
				$request.AddNewChild("snapshot-lun-path",$FromSnapshot)
				if ($OSType) {
					$request.AddNewChild("type", $OSType)
				}
			
			} else {
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-by-size")
				$request.AddNewChild("size",$Size)
				if ($OSType) {
					$request.AddNewChild("OStype", $OSType)
				}
			}
		}
		Else {
			if ($FromFile) {
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-file")
				$request.AddNewChild("file-name",$FromFile)
				if ($OSType) {
					$request.AddNewChild("type", $OSType)
				}
			} elseif ($FromSnapshot) {
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-snapshot")
				$request.AddNewChild("snapshot-lun-path",$FromSnapshot)
				if ($OSType) {
					$request.AddNewChild("type", $OSType)
				}
			
			} else {
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-by-size")
				$request.AddNewChild("size",$Size)
				if ($OSType) {
					$request.AddNewChild("type", $OSType)
				}
			}
		}
		$request.AddNewChild("path",$Path)
		if ($NoSpaceReserve) {
			$request.AddNewChild("space-reservation-enabled",$FALSE)
		} else {
			$request.AddNewChild("space-reservation-enabled",$TRUE)
		}
		if ($pscmdlet.ShouldProcess($Server.server, "Creating lun $Path")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?){
				return Get-NaLun -Path $Path -Server $Server
			}
		}
	}
}
Function Set-NaLun {
	<#
	.Synopsis
  	 	Create a new lun
	.Description
   		Create a new lun, with initially zero contents. The lun is 
   		created at the path given. No file should already exist at the given 
   		path.
	.Parameter Path
   		Path of the LUN. 
   	.Parameter Offline
   		Disables block-protocol accesses to the LUN. Mappings, if any, configured 
   		for the lun are not altered. Note that unless explicitly offlined, a lun 
   		is online.
   	.Parameter Online
   		Re-enables block-protocol accesses to the lun.
   	.Parameter Force
 		Forcibly online the lun, disabling mapping onflict checks with the cluster
 		partner. If not specified all conflict checks are performed. 
   	.Parameter Description
   		Set the optional descriptive comment for a LUN.
   	.Parameter SerialNumber
   		Set the serial number for the specified LUN. The lun must first be made 
   		offline before changing the serial number. The serial number is a 
   		12-character string formed of upper and lower-case letters, numbers, and 
   		slash (/) and hyphen (-) characters.
   	.Parameter DeviceID
   		Set the SCSI Device Identifier for the Lun.
	.Parameter Server
   		NaServer to query
	.Example
		# offline lun0
		PS > Set-NaLun -Path /vol/vol1/lun0 -offline
	.Example
		# online lun0
		PS > Set-NaLun -Path /vol/vol1/lun0 -online
	.Example 
		# Set the description for the /vol/vol1/vmdata lun
		PS > Set-NaLun -Path /vol/vol1/vmdata -Description "testing lun"
	.Outputs
    	NetApp.SDK.NaLun[]
    .Link
		Get-NaLun
		New-NaLun
		Remove-NaLun
   	.Notes 
	    NAME:     Set-NaLun
	    AUTHOR:   Glenn Sizemore
	    #Requires -Version 2.0 
	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param(
		[Parameter(ParameterSetName="offline",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
		[Parameter(ParameterSetName="online",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
		[Parameter(ParameterSetName="desc",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
		[Parameter(ParameterSetName="sn",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
		[Parameter(ParameterSetName="deviceID",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
	    [string]
	    $Path,
		
		[Parameter(ParameterSetName="offline")]
	    [switch]
	    $Offline,
		
		[Parameter(ParameterSetName="online")]
		[switch]
		$Online,
		
		[Parameter(ParameterSetName="desc")]
		[string]
		$Description,
		
		[Parameter(HelpMessage="Set the serial number for the specified LUN.",ParameterSetName="sn")]
		[string]
		$SerialNumber,
		
		[Parameter(HelpMessage="Set the SCSI Device Identifier for the Lun.",ParameterSetName="deviceID")]
		[string]
		$DeviceID,
		
		[Parameter(ParameterSetName="online")]
		[switch]
		$Force,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		switch ($PSCmdlet.ParameterSetName)
		{
			"online"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-online")
				$msg = "Online Lun $($path)"
				if ($force) {
					$request.AddNewChild("force",$TRUE)
				}
			}
			"offline"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-offline")
				$msg = "Offline Lun $($path)"
			}
			"desc"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-set-comment")
				$request.AddNewChild("comment",$Description)
				$msg = "Setting $($path) description to $($Description)"
			}
			"sn"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-set-serial-number")
				$request.AddNewChild("serial-number",$SerialNumber)
				$msg = "Changing $($path) serial number to $($serialNumber)"
			}
			"deviceID"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-set-device-id")
				$request.AddNewChild("device-id",$DeviceID)
				$msg = "Changing $($path) SCSI Device Identifier to $($DeviceID)"
			}
		}
		$request.AddNewChild("path",$path)
		if ($pscmdlet.ShouldProcess($path,$msg)) {
			try {
				$server.InvokeElem($request)#|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?){
				return Get-NaLun -Path $Path -Server $Server
			}
		}
	}
}
Function Remove-NaLun {
	<#
	.Synopsis
  	 	Destroy the specified LUN.
	.Description
   		Destroy the specified LUN. This operation will fail if the LUN is currently 
   		mapped and is online. The force option can be used to destroy it regardless 
   		of being online or mapped.
	.Parameter Path
   		Path of the LUN. 
   	.Parameter Force
   		Forcibly destroy the LUN regardless of it being online or mapped.
	.Parameter Server
   		NaServer to query
	.Example
		# Delete the /vol/vol1/lun6 lun
		PS > Set-NaLun -Path /vol/vol1/lun6 | Remove-NaLun -confirm
    .Link
		Get-NaLun
		New-NaLun
		Set-NaLun
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="high",DefaultParameterSetName="")]
	param(
	    [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
	    [string]
	    $Path,
	
		[Parameter()]
		[switch]
		$Force,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-destroy")
		if ($force) {
			$request.AddNewChild("force",$TRUE)
		}
		$request.AddNewChild("path",$path)
		if ($pscmdlet.ShouldProcess($server.server,"Destroying lun $path")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
		}
	}
}
function Set-NaLunSize {
	<#
	.Synopsis
  	 	Changes the size of the lun.
	.Description
   		Changes the size of the lun. Note that client-side operations may be needed 
   		to ensure that client software recognizes the changed size.
	.Parameter Path
   		Path of the LUN. 
   	.Parameter Size
   		New size for the LUN. 
   	.Parameter Force
 		Forcibly reduce the size. This is required for reducing the size of the LUN 
 		to avoid accidentally reducing the LUN size. 
	.Parameter Server
   		NaServer to query
	.Example
		Resize Lun0 to 50GB
		PS > Set-NaLunSize -Path /vol/vol1/Lun0 -Size 50GB
	.Outputs
    	PSObject
    .Link
		Get-NaLun
		New-NaLun
		Remove-NaLun
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param(
	    [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
	    [string]
	    $Path,
		
		[Parameter(Position=1,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="New size for the LUN in Bytes.")]
		[int]
	    $Size,
	
		[Parameter()]
		[switch]
		$Force,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-resize")
		if ($force) {
			$request.AddNewChild("force",$TRUE)
		}
		$request.AddNewChild("path",$Path)
		$request.AddNewChild("size",$Size)
		if ($pscmdlet.ShouldProcess($server.server, "Resizing $Path to $($size/1mb)MB")) {	
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?){
				return Get-NaLun -Path $Path -Server $Server
			}
		}
	}
}
function Move-NaLun {
	<#
	.Synopsis
  	 	Move (rename) a LUN.
	.Description
   		Move (rename) a LUN.
	.Parameter Path
   		Path of the LUN. 
   	.Parameter NewPath
   		New path of the LUN being moved to.
   	.Parameter Server
   		NaServer to query
	.Example
		Move/Rename Lun0 to Lun1
		PS > Move-NaLunSize -Path /vol/vol1/Lun0 -NewPath /vol/vol1/Lun1
	.Outputs
    	PSObject
    .Link
		Get-NaLun
		New-NaLun
		Set-NaLun
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param(
	    [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
	    [string]
	    $Path,
	
		[Parameter(Position=1,Mandatory=$TRUE,HelpMessage="New path of the LUN being moved(renamed) to.")]
		[string]
		$NewPath,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-move")
		$request.AddNewChild("path",$path)
		$request.AddNewChild("new-path",$NewPath)
		if ($pscmdlet.ShouldProcess("moving $path to $NewPath ")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?){
				return Get-NaLun -Path $NewPath -Server $Server
			}
		}
	}
}
Function Test-NaLunPortSCSIReservations {
	<#
	.Synopsis
  	 	Queries for all types of scsi reservations.
	.Description
   		Queries for all types of scsi reservations covering both iSCSI and FCP
   		for a given initiator portname. 
	.Parameter Path
   		Path of the LUN. 
   	.Parameter PortName
   		Name of the port. 
   	.Parameter Server
   		NaServer to query
	.Example
		
	.Outputs
    	Bool
    .Link
		Get-NaLun
		New-NaLun
		Set-NaLun
   	#> 
	[CmdletBinding(SupportsShouldProcess=$False,SupportsTransactions=$False,ConfirmImpact="none",DefaultParameterSetName=""	)]
	param(
	    [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")]
	    [string]
	    $Path,
	
		[Parameter(Position=1,Mandatory=$TRUE,HelpMessage="Name of the port.")]
		[string]
		$portname,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-port-has-scsi-reservations")
		$request.AddNewChild("path",$path)
		$request.AddNewChild("portname",$portname)
		try {
			$result  = ([xml]$server.InvokeElem($request)).results
		}
		catch [NetApp.Manage.NaApiFailedException]{
			Write-Warning $_.Exception.GetBaseException().message
			$result = $null
			continue;
		}
		if ($?) {
			return ConvertFrom-NaBool $result."is-reservation-held"
		}
	}
}
Function Get-NaLunMap {
	<#
	.Synopsis
  	 	Returns a list of initiator groups and their members (the initiators) 
		mapped to the given LUN.
	.Description
   		Returns a list of initiator groups and their members (the initiators) 
		mapped to the given LUN.
	.Parameter Path
   		LUN for which the initiator group list is requested. 
	.Parameter Server
   		NaServer to query
	.Example
		# Get the Lun Map info for all luns
		PS > Get-NaLun | Get-NaLunMap
	.Outputs
    	NetApp.SDK.NaLun[]
    .Link
		Set-NaLun
		New-NaLun
		Remove-NaLun
		Move-NaLun
		Set-NaLunSize
   	#> 
	[CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")]
		[string]
		$Path,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-map-list-info")
		$request.AddNewChild("path",$Path)
		try {
			$result  = ([xml]$server.InvokeElem($request)).results
		}
		catch [NetApp.Manage.NaApiFailedException]{
			Write-Warning $_.Exception.GetBaseException().message
			$result = $null
			continue;
		}
		if ($?){
			$result."initiator-groups"."initiator-group-info" |
			?{$_."initiator-group-name"}|% {
				return New-Object NetApp.SDK.NaLunMap -ArgumentList @(
					$Path,
					$_."initiator-group-name",
					$_."lun-id",
					$_."initiator-group-os-type",
					$_."initiator-group-portset-name",
					$_."initiator-group-type",
					[array]($_."initiators"."initiator-info"|%{$_."initiator-name"}),
					(ConvertFrom-NaBool $_."initiator-group-alua-enabled"),
					(ConvertFrom-NaBool $_."initiator-group-throttle-borrow"),
					$_."initiator-group-throttle-reserve",
					(ConvertFrom-NaBool $_."initiator-group-vsa-enabled"),
					(ConvertFrom-NaBool $_."initiator-group-use-partner")
				)
			}
		}
	}
}
function Add-NaLunMap {
	<#
	.Synopsis
  	 	Maps the LUN to all the initiators in the specified initiator group.
	.Description
   		Maps the LUN to all the initiators in the specified initiator group.
	.Parameter Path
   		LUN for which the initiator group list is requested. 
	.Parameter IGroup	
		Initiator group to map to the given LUN. 
	.Parameter LunID
		If the lun-id is not specified, the smallest number that can be used for
		the various initiators in the group is automatically picked. 
	.Parameter Force
		Forcibly map the lun, disabling mapping conflict checks with the cluster 
		partner. If not specified all conflict checks are performed. 
	.Parameter Server
   		NaServer to query
	.Example
		# Map /vol/vmdata3/lun3 to the VMware IGroup with a lunID of 3
		PS > Add-NaLunMap -Path /vol/vmdata3/lun3 -IGroup VMware -LunID 3
	.Outputs
    	NetApp.SDK.NaLunMap[]
    .Link
		Get-NaLun
		Get-NaLunMap
		Remove-NaLunMap
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")]
		[string]
		$Path,
		
		[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Initiator group to map to the given LUN. ")]
		[string]
		$IGroup,
		
		[Parameter(ValueFromPipelineByPropertyName=$TRUE,HelpMessage="ID to map lun to.")]
		[string]
		$LunID,
		
		[Parameter(ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Forcibly map the lun.")]
		[string]
		$Force,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-map")
		$request.AddNewChild("path",$Path)
		$request.AddNewChild("initiator-group",$IGroup)
		if ($LunID) {
			$request.AddNewChild("lun-id",$LunID)
		}
		if ($Force) {
			$request.AddNewChild("force",$Force)
		}
		if ($pscmdlet.ShouldProcess($Server.server, "Mapping $Path to $($IGroup):$($LunID)")) {
			Try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?){
				return Get-NaLunMap -Path $Path -Server $Server
			}
		}
	}
}
function Remove-NaLunMap {
	<#
	.Synopsis
  	 	Reverses the effect of lun-map on the specified LUN for the specified group.
	.Description
   		Reverses the effect of lun-map on the specified LUN for the specified group.
	.Parameter Path
   		Path of the LUN. 
	.Parameter IGroup 
		Name of the IGroup to unmap.
	.Parameter Server
   		NaServer to query
	.Example
		Get-NaLunMap -Path /vol/vol1/lun1 -IGroup VMware
	.Example
		Get-NaLun | Get-NaLunMap |?{$_.IGroup -match "VMware2"}|Remove-NaLunMap
	.Outputs
    	NetApp.SDK.NaLunMap[]
    .Link
		Get-NaLun
		Get-NaLunMap
		Add-NaLunMap
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="high",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")]
		[string]
		$Path,
	
		[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Initiator group to map to the given LUN.")]
		[string]
		$IGroup,
		
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-unmap")
		$request.AddNewChild("path",$Path)
		$request.AddNewChild("initiator-group",$IGroup)
		if ($pscmdlet.ShouldProcess($Server.server, "Unmapping $($Path) From $($IGroup)")) {
			Try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
			if ($?){
				return Get-NaLunMap -Path $Path -Server $Server
			}
		}
	}
}

